home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / XPK / Source / prefs / XpkMaster.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-06-18  |  40.6 KB  |  1,526 lines

  1. #define NAME     "XpkMaster"
  2. #define REVISION "30"
  3. #define ENDCODE
  4.  
  5. /* Programmheader
  6.  
  7.     Name:        XpkMaster
  8.     Author:        SDI
  9.     Distribution:    PD
  10.     Description:    Prefs program for XpkMaster
  11.     Compileropts:    -
  12.     Linkeropts:    -l amiga
  13.     ToDo:        speed up refresh, by flags based choose of to
  14.             refresh gadgets
  15.  
  16.  1.0   10.11.96 : first Version, incomplete, started to form GUI
  17.  1.1   11.11.96 : corrected, added the code a bit
  18.  1.2   16.11.96 : some more stuff
  19.  1.3   17.11.96 : completed GUI
  20.  1.4   20.11.96 : added more functions
  21.  1.5   21.11.96 : added icon creation, corrected some stuff
  22.  1.6   23.11.96 : corrected some stuff
  23.  1.7   24.11.96 : added loading and cleaned up source
  24.  1.8   30.11.96 : fixed some errors, still working incorrect
  25.  1.9   01.12.96 : and again some bugfixes
  26.  1.10  07.12.96 : correct Default dir in asl request and wb call
  27.  1.11  12.12.96 : fixed crash problem, when called by project icon with
  28.      ACTION=EDIT
  29.  1.12  13.12.96 : made the window a bit smaller for larger texts and fonts
  30.  1.13  14.12.96 : changed the Prefs include XPKM -> XPKT, XPKD -> XPKM,
  31.      other member prefixes
  32.  1.14  20.12.96 : fixed Enforcer hit (I finally have a MMU :-) and little
  33.     error
  34.  1.15  25.12.96 : corrected List handling
  35.  1.16  26.12.96 : once again changed xpkprefs.h -> now should be last time,
  36.      because I wrote the prefs support for master library
  37.  1.17  29.12.96 : fixed bug with XPKM flags
  38.  1.18  09.01.97 : changed default flags
  39.  1.19  11.01.97 : splitted master library and prefs catalog
  40.  1.20  01.03.97 : changed XpkMainPrefs structure a bit
  41.  1.21  07.03.97 : recompiled, because of structures additions
  42.  1.22  08.03.97 : fixed a crash causing typo error
  43.  1.23  02.04.97 : changed XpkTypeData structure
  44.  1.24  03.04.97 : fixed error
  45.  1.25  04.04.97 : fixed error in texts
  46.  1.26  10.04.97 : default entry now 1 and not 0
  47.  1.27  18.05.97 : corrected internal string
  48.  1.28  31.05.97 : SDI_locale changed
  49.  1.29  17.06.97 : now prints entry name for illegal entry
  50.  1.30  18.06.97 : library name file requester got wrong value
  51. */
  52.  
  53. #include <pragma/exec_lib.h>
  54. #include <pragma/intuition_lib.h>
  55. #include <pragma/dos_lib.h>
  56. #include <pragma/icon_lib.h>
  57. #include <pragma/gadtools_lib.h>
  58. #include <pragma/graphics_lib.h>
  59. #include <pragma/asl_lib.h>
  60. #include <pragma/iffparse_lib.h>
  61. #include <xpk/xpkprefs.h>
  62. #include <clib/alib_protos.h>
  63. #include <intuition/gadgetclass.h>
  64. #include <workbench/startup.h>
  65. #include <prefs/prefhdr.h>
  66. #include <exec/memory.h>
  67. #include "SDI_defines.h"
  68. #define SDI_LOCALE_NO_STRUCTS
  69. #include "SDI_locale.c"
  70. #include "SDI_ASM_STD_protos.h"
  71.  
  72. /* ------------------ defines and structures --------------------------- */
  73.  
  74. #define PARAM    "FROM,EDIT/S,USE/S,SAVE/S,PUBSCREEN/K"
  75.  
  76. #define GADGET(a)     ((struct Gadget *) a->IAddress)
  77. #define STRINF(a)    ((struct StringInfo *) (a->SpecialInfo))
  78. #define    DEFNODE(a)    ((struct PackerNode *) ((a)->ld_List.lh_Head))
  79.  
  80. #define PicSize        509    // size of the icon
  81.  
  82. enum {
  83. STRING_TypeName = 100,    LISTVIEW,        BUTTON_New,
  84. BUTTON_Delete,        BUTTON_Up,        BUTTON_Down,
  85. STRING_NamePatt,    STRING_FilePatt,    STRING_LibraryName,
  86. GETIMAGE,        INTEGER_Mode,        INTEGER_ChunkSize,
  87. CYCLE,            INTEGER_TimeOut,    CHECKBOX_XFD,
  88. CHECKBOX_EXT,        CHECKBOX_Password,    BUTTON_Save,
  89. BUTTON_Use,        BUTTON_Chancel
  90. };
  91.  
  92. #define PREF_VERSION    0    // version of prefs I can work with
  93.  
  94. #define    DEFAULT_NODE    100
  95. #define PACKER_NODE    101
  96.  
  97. #define DEF_TIMEOUT    120
  98. #define DEF_XPKM_FLAGS    (XPKM_AutoPassword | XPKM_UseExternals)
  99. #define DEF_CYCLE    2 // XTD_ReturnError
  100.  
  101. // window style defines
  102. #define SEPARATE_SAME    2
  103. #define SEPARATE_DIFF    5
  104. #define SEPARATE_BORD    5
  105.  
  106. #define TypeSIZE    49
  107. #define NamePattSIZE    49
  108. #define FilePattSIZE    99
  109.  
  110. struct PackerNode {
  111.   struct Node        pn_Node;
  112.   ULONG            pn_StdID;
  113.   UWORD            pad;    /* always StdID finished with 0 byte */
  114.   UWORD            pn_Mode;
  115.   ULONG            pn_ChunkSize;
  116.   ULONG            pn_Cycle;
  117.   UBYTE            pn_TypeName[TypeSIZE+1];
  118.   UBYTE            pn_NamePattern[NamePattSIZE+1];
  119.   UBYTE            pn_FilePattern[FilePattSIZE+1];
  120. };
  121.  
  122. struct ListData {
  123.   struct List    ld_List;
  124.   struct PackerNode    *ld_curNode;
  125.   ULONG            ld_entries;
  126.   ULONG            ld_curNumber;
  127. };
  128.  
  129. struct Args {
  130.   STRPTR from;
  131.   ULONG     edit;
  132.   ULONG     use;
  133.   ULONG  save;
  134.   STRPTR pubscreen;
  135.   ULONG     createicons;
  136. };
  137.  
  138. /* ----------------------------- Strings ------------------------------- */
  139.  
  140. #define TEXT_START_MENUMAIN    0
  141. #define NUMBER_MENUMAIN        11
  142.  
  143. enum {
  144. TEXT_WINDOW_TITLE = NUMBER_MENUMAIN,        TEXT_ENTRY_DEFAULT,
  145. TEXT_ENTRY_NEW,        TEXT_SELECT_LIBRARY,    TEXT_LOAD_PREFERENCES,
  146. TEXT_SAVE_PREFERENCES,    TEXT_TITLE_ERR_REQUEST,    TEXT_ERROR_FILEACCESS,
  147. TEXT_LIB_REQUIRED,    TEXT_VERSION_TO_HIGH,    TEXT_ERROR_FILEPROCESS,
  148. TEXT_ILLEGAL_ENTRY,    TEXT_NO_WINDOW,        GADGS_ERR_REQUEST,
  149. GADG_Save,        GADG_Use,        GADG_Cancel,
  150. GADG_Use_XFD,        GADG_Use_Externals,    GADG_AutoPassword,
  151. GADG_Timeout,        GADG_New,        GADG_Delete,
  152. GADG_Up,        GADG_Down,        GADG_Name_Pattern,
  153. GADG_File_Pattern,    GADG_Library_Name,    GADG_Mode,
  154. GADG_ChunkSize,        GADG_PackMode,        TEXT_START_SLIDER
  155. };
  156.  
  157. #define TEXT_START_OTHER    (NUMBER_MENUMAIN)
  158. #define TEXT_START_GADGET    (GADG_Save)
  159.  
  160. #define NUMBER_OTHER        (TEXT_START_GADGET-TEXT_START_OTHER)
  161. #define NUMBER_GADGET        (TEXT_START_SLIDER-TEXT_START_GADGET)
  162. #define NUMBER_SLIDER        3
  163.  
  164. struct SDI_SetLocale initloc[] = {
  165. { 400, NUMBER_MENUMAIN, TEXT_START_MENUMAIN}, // Main-Menutexts
  166. { 420, NUMBER_OTHER,    TEXT_START_OTHER},    // all other texts
  167. { 450, NUMBER_SLIDER,   TEXT_START_SLIDER},   // Slider texts
  168. { 460, NUMBER_GADGET,   TEXT_START_GADGET},   // Gadgettexts
  169. {   0, 0, 0},                      // Ende
  170. };
  171.  
  172. STRPTR text[] =
  173. {
  174. "Project",
  175. "O\0Open...",
  176. "M\0Load Add...",
  177. "A\0Save As...",
  178. "Q\0Quit",
  179. "Edit",
  180. "D\0Reset To Defaults",
  181. "L\0Last Saved",
  182. "R\0Restore",
  183. "Settings",
  184. "I\0Create Icons?",
  185. "XpkMaster Preferences",    // the window title
  186. "«default»",            // the default pack mode
  187. "«new»",
  188. "Select xpk or xex library",
  189. "Load XpkMaster preferences",
  190. "Save XpkMaster preferences",
  191. "Program Error",
  192. "Error accessing file\n%s\n%s",
  193. "Requires %s V%ld",
  194. "Prefs file version to high,\nloaded data may be incomplete.",
  195. "Error processing IFF file",
  196. "%s of entry %ld (%s)\nis illegal, cannot save.",
  197. "Could not open window,\nthe used font is too large.",
  198. "OK",
  199. "Save",
  200. "Use",
  201. "Cancel",
  202. "Use XFD",            // the checkboxes
  203. "Use XEX",
  204. "Auto password",
  205. "Timeout",            // the timeout integer
  206. "New",                // the Listview
  207. "Delete",
  208. "Up",
  209. "Down",
  210. "Name Pattern",
  211. "File Pattern",
  212. "Library Name",
  213. "Mode",
  214. "ChunkSize",
  215. "PackMode",
  216.  
  217. "pack xpk or xex",
  218. "do not pack",
  219. "return error",
  220. 0,
  221. };
  222.  
  223. STRPTR toolt[] =
  224. {
  225. "EDIT",
  226. "USE",
  227. "SAVE",
  228. "PUBSCREEN",
  229. "CREATEICONS",    // YES || NO
  230. "ACTION"
  231. };
  232.  
  233. /* ---------------------- protos and variables ------------------------- */
  234.  
  235. struct RDArgs        *rda        = 0;
  236. struct Library        *GadToolsBase    = 0,
  237.             *IconBase    = 0,
  238.             *UtilityBase    = 0,
  239.             *AslBase    = 0,
  240.             *IFFParseBase    = 0;
  241. struct LocaleBase    *LocaleBase    = 0;
  242. struct IntuitionBase    *IntuitionBase    = 0;
  243. struct GfxBase        *GfxBase    = 0;
  244. struct Screen        *Scr        = 0;
  245. APTR            VisualInfo    = 0;
  246. struct Window        *window        = 0;
  247. struct Gadget        *gadgList    = 0,
  248.             *gadgdata[12];
  249. /* List, NamePatt, FilePatt, LibraryName, GetImage, Mode, ChunkSize, Cycle,
  250. TimeOut, XFD, Extern, Pwd */
  251. struct Menu        *menus        = 0;
  252. struct DiskObject    *diskobject    = 0;
  253. ULONG            lock        = 0,
  254.             DosVersion    = 37,
  255.             TimeOut        = DEF_TIMEOUT,
  256.             XPKM_Flags    = DEF_XPKM_FLAGS;
  257. struct ListData        maindata    = {{(struct Node *) &maindata.ld_List.lh_Tail,
  258.      0, (struct Node *) &maindata.ld_List.lh_Head, NT_USER, 0}, 0, 0, 0};
  259. UBYTE            namestring[256];
  260. struct SDI_LocaleData    locdat = {"xpkmasterprefs.catalog", 1, 0,0,0,0};
  261.  
  262. #ifdef __MAXON__
  263. extern "C" void        wbmain(struct WBStartup *);
  264. void            main(void);
  265. #else
  266. void            wbmain(struct WBStartup *);
  267. void            main(int argc, char **argv);
  268. #endif
  269. void            Work(struct Args *);
  270. ULONG            SDIConvToUpper(STRPTR a);
  271.  
  272. void            CorrectAdr(APTR, APTR);
  273. void            CopyStrings(STRPTR, STRPTR, ULONG);
  274. void            CopyLibName(struct XpkTypeData *, struct PackerNode *);
  275. void            ReadXPKM(struct XpkMainPrefs *, struct ListData *);
  276. ULONG            ReadXPKT(struct XpkTypePrefs *, struct ListData *);
  277. ULONG            LoadFile(STRPTR, ULONG);
  278.  
  279. ULONG            CopyData(STRPTR, ULONG *, APTR, STRPTR *);
  280. ULONG            WriteXPKM(struct IFFHandle *);
  281. ULONG            WriteXPKT(struct IFFHandle *, struct PackerNode *, ULONG);
  282. ULONG            SaveFile(STRPTR, ULONG);
  283.  
  284. void            PrintError(STRPTR, ...);
  285. void            FileReq(void);
  286. ULONG            PrefsFileReq(STRPTR, ULONG, STRPTR);
  287. void            FreeListView(void);
  288. void            ResetListView(ULONG, struct ListData *);
  289. void            SetMainData(void);
  290. ULONG             DoWindow(void);
  291.  
  292. void            NewPackerList(struct ListData *);
  293. void            FreePackerList(struct ListData *);
  294. struct Node        *FindNode(struct List *, ULONG);
  295. struct PackerNode    *NewPackerNode(struct ListData *, STRPTR, struct PackerNode *, ULONG);
  296.  
  297. struct NewMenu NewMenus[] = {
  298.   NM_TITLE, (STRPTR) &text[TEXT_START_MENUMAIN],   0, 0, 0, 0,
  299.   NM_ITEM,  (STRPTR) &text[TEXT_START_MENUMAIN+1], 0, 0, 0, 0,
  300.   NM_ITEM,  (STRPTR) &text[TEXT_START_MENUMAIN+2], 0, 0, 0, 0,
  301.   NM_ITEM,  (STRPTR) &text[TEXT_START_MENUMAIN+3], 0, 0, 0, 0,
  302.   NM_ITEM,  (STRPTR) NM_BARLABEL, 0, 0, 0, 0,
  303.   NM_ITEM,  (STRPTR) &text[TEXT_START_MENUMAIN+4], 0, 0, 0, 0,
  304.   NM_TITLE, (STRPTR) &text[TEXT_START_MENUMAIN+5], 0, 0, 0, 0,
  305.   NM_ITEM,  (STRPTR) &text[TEXT_START_MENUMAIN+6], 0, 0, 0, 0,
  306.   NM_ITEM,  (STRPTR) &text[TEXT_START_MENUMAIN+7], 0, 0, 0, 0,
  307.   NM_ITEM,  (STRPTR) &text[TEXT_START_MENUMAIN+8], 0, 0, 0, 0,
  308.   NM_TITLE, (STRPTR) &text[TEXT_START_MENUMAIN+9], 0, 0, 0, 0,
  309.   NM_ITEM,  (STRPTR) &text[TEXT_START_MENUMAIN+10], 0, MENUTOGGLE|CHECKIT, 0, 0,
  310.   NM_END,   0, 0, 0, 0, 0};
  311.  
  312. ULONG PicData[] = {
  313.   0xE3100001,0x00000000,0x0023000F,0x00360017,0x00050003,0x00010044,
  314.   0x39A00000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,
  315.   0x049C004D,0x0CE00033,0x80F88000,0x00008000,0x00000000,0x00000000,
  316.   0x00000000,0x10000000,0x00000036,0x00170002,0x00024288,0x03000000,
  317.   0x00000000,0x00000004,0x00000000,0x00000001,0x00000000,0x07FF8000,
  318.   0x40000000,0x18006000,0x10000000,0x20FC1000,0x08000000,0x41020800,
  319.   0x0C000000,0x40820800,0x0C000000,0x40820800,0x0C000000,0x21040800,
  320.   0x0C000000,0x1E181000,0x0C000000,0x00602000,0x0C000000,0x0080C000,
  321.   0x0C000000,0x01030000,0x0C000000,0x021C0000,0x0C000000,0x01080000,
  322.   0x0C000000,0x00F00000,0x0C000000,0x01080000,0x0C000000,0x01080000,
  323.   0x0C004000,0x00F00000,0x0C001000,0x00000000,0x0C000400,0x00000000,
  324.   0x0C0001FF,0xFFFFFFFF,0xFC000000,0x00000000,0x0000FFFF,0xFFFFFFF8,
  325.   0x0000D555,0x55555556,0x0000D555,0x50005555,0x8000D555,0x47FF9555,
  326.   0x6000D555,0x5F03E555,0x5000D555,0x3E55F555,0x5000D555,0x3F55F555,
  327.   0x5000D555,0x3F55F555,0x5000D555,0x5E53F555,0x5000D555,0x4147E555,
  328.   0x5000D555,0x551FD555,0x5000D555,0x557F1555,0x5000D555,0x54FC5555,
  329.   0x5000D555,0x55E15555,0x5000D555,0x54F55555,0x5000D555,0x55055555,
  330.   0x5000D555,0x54F55555,0x5000D555,0x54F55555,0x50003555,0x55055555,
  331.   0x50000D55,0x55555555,0x50000355,0x55555555,0x50000000,0x00000000,
  332.   0x00000000,0x00000000,0x00000000,0x00145359,0x533A5072,0x6566732F,
  333.   0x58706B4D,0x61737465,0x72000000,0x00080000,0x000B4143,0x54494F4E,
  334.   0x3D555345,0x00000000,
  335. };
  336.  
  337. /* -------------------------- central functions ------------------------ */
  338.  
  339. void wbmain(struct WBStartup *wb)
  340. {
  341.   struct Args args = {0, 0, 0, 0, 0, 0};
  342.  
  343.   if(wb->sm_NumArgs > 2 || !wb->sm_NumArgs)
  344.     End(RETURN_FAIL);
  345.  
  346.   lock = CurrentDir(wb->sm_ArgList[wb->sm_NumArgs-1].wa_Lock);
  347.  
  348.   if((IconBase = OpenLibrary("icon.library", 37)) &&
  349.   (diskobject = GetDiskObject(wb->sm_ArgList[wb->sm_NumArgs-1].wa_Name)))
  350.   {
  351.     STRPTR a, *c = (STRPTR *) diskobject->do_ToolTypes;
  352.  
  353.     if(wb->sm_NumArgs == 2)
  354.       args.from = wb->sm_ArgList[1].wa_Name;
  355.  
  356.     args.edit = (ULONG) FindToolType(c, toolt[0]);
  357.     args.use = (ULONG) FindToolType(c, toolt[1]);
  358.     args.save = (ULONG) FindToolType(c, toolt[2]);
  359.     args.pubscreen = FindToolType(c, toolt[3]);
  360.     if((a = FindToolType(c, toolt[4])))
  361.     {
  362.       if(MatchToolValue(a, "YES"))
  363.         args.createicons = 1;
  364.     }
  365.     if((a = FindToolType(c, toolt[5])))
  366.     {
  367.       if(MatchToolValue(toolt[0], a))
  368.         args.edit = 1;
  369.       else if(MatchToolValue(toolt[1], a))
  370.         args.use = 1;
  371.       else if(MatchToolValue(toolt[2], a))
  372.         args.save = 1;
  373.     }
  374.   }
  375.  
  376.   Work(&args);
  377.   End(RETURN_OK);
  378. }
  379.  
  380. #ifdef __MAXON__
  381. void main(void)
  382. #else
  383. void main(int argc, char **argv)
  384. #endif
  385. {
  386.   struct Args args = {0, 0, 0, 0, 0, 0};
  387.  
  388. #ifdef __SASC
  389.   TestOS;
  390.   if(!argc)
  391.     wbmain((struct WBStartup *) argv);
  392. #endif
  393.  
  394.   if(!(rda = ReadArgs(PARAM, (LONG *) &args, 0)))
  395.     End(RETURN_FAIL);
  396.  
  397.   Work(&args);
  398.   End(RETURN_OK);
  399. }
  400.  
  401. void Work(struct Args *args)
  402. {
  403.   struct IntuiMessage *IntuiMessagePtr;
  404.   ULONG run = 1;
  405.   LONG Long;
  406.   STRPTR txt;
  407.  
  408.   if(args->edit)
  409.     args->use = args->save = 0;
  410.   if(args->save)
  411.     args->use = 0;
  412.  
  413.   if(
  414.   !(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 37)) ||
  415.   !(GadToolsBase = OpenLibrary("gadtools.library", 37)) ||
  416.   !(UtilityBase = OpenLibrary("utility.library", 37)) ||
  417.   !(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",37)))
  418.     End(RETURN_FAIL);
  419.  
  420.   SDI_InitLocale(&locdat);
  421.   SDI_LocaleStrings(&locdat, initloc, text);
  422.   SDI_LocaleNewMenu(NewMenus, text + TEXT_START_MENUMAIN,
  423.     text + TEXT_START_OTHER);
  424.  
  425.   if(!(IFFParseBase = OpenLibrary("iffparse.library", 37)))
  426.   {
  427.     PrintError(text[TEXT_LIB_REQUIRED], "iffparse.library", 37);
  428.     End(RETURN_FAIL);
  429.   }
  430.  
  431.   NewPackerList(&maindata);
  432.  
  433.   if(args->use || args->save)
  434.   {
  435.     if(!args->from)
  436.       args->from = "";
  437.     if(LoadFile(args->from, 0) ||
  438.     (args->save && SaveFile((STRPTR)1 , 0)) ||
  439.     SaveFile(0, 0))
  440.       End(RETURN_FAIL);
  441.     End(RETURN_OK);
  442.   }
  443.  
  444.   if(args->createicons)
  445.     NewMenus[11].nm_Flags |= CHECKED;
  446.  
  447.   if(args->from && LoadFile(args->from, 0))
  448.     args->from = 0;
  449.  
  450.   if(!args->from && LoadFile(0, 0))
  451.     LoadFile((STRPTR) 1, 0);
  452.  
  453.   if(!(Scr = LockPubScreen(args->pubscreen)) ||
  454.   !(VisualInfo = GetVisualInfoA(Scr, 0)) ||
  455.   DoWindow())
  456.     End(RETURN_FAIL);
  457.  
  458.   do
  459.   {
  460.     if(Wait((1L<<window->UserPort->mp_SigBit)|SIGBREAKF_CTRL_C)
  461.     == SIGBREAKF_CTRL_C)
  462.       run = 0;
  463.     else
  464.       while(run && (IntuiMessagePtr = GT_GetIMsg(window->UserPort)))
  465.       {
  466.     switch(IntuiMessagePtr->Class)
  467.      {
  468.     case IDCMP_MENUPICK:
  469.       Long = (ULONG) IntuiMessagePtr->Code;
  470.       while(run && (ULONG) Long != MENUNULL)
  471.       {
  472.         switch(MENUNUM((ULONG) Long))
  473.         {
  474.         case 0:                    // Projekt
  475.           switch(ITEMNUM((ULONG) Long))
  476.           {
  477.           case 0:                    // Open...
  478.         if(PrefsFileReq(args->from, 0, text[TEXT_LOAD_PREFERENCES]))
  479.         {
  480.           args->from = namestring;
  481.           LoadFile(args->from, 0);
  482.                SetMainData();
  483.           ResetListView(0, &maindata);
  484.         }
  485.         break;
  486.           case 1:                    // Load Add...
  487.         if(PrefsFileReq(args->from, 0, text[TEXT_LOAD_PREFERENCES]))
  488.         {
  489.           args->from = namestring;
  490.           LoadFile(args->from, 1);
  491.               ResetListView(0, &maindata);
  492.         }
  493.         break;
  494.           case 2:                    // Save As...
  495.         if(PrefsFileReq(args->from, 1, text[TEXT_SAVE_PREFERENCES]))
  496.         {
  497.           args->from = namestring;
  498.           SaveFile(args->from, args->createicons);
  499.         }
  500.         break;
  501.           case 4: run = 0; break;            // Quit
  502.           } break;
  503.         case 1:                    // Edit
  504.           switch(ITEMNUM((ULONG) Long))
  505.           {
  506.           case 0:                    // Reset To Defaults
  507.         NewPackerList(&maindata);
  508.         ResetListView(0, &maindata);
  509.         break;
  510.           case 1:                    // Last Saved
  511.         LoadFile((STRPTR) 1, 0);
  512.         SetMainData();
  513.             ResetListView(0, &maindata);
  514.         break;
  515.           case 2:                    // Restore
  516.         LoadFile(0, 0);
  517.             SetMainData();
  518.         ResetListView(0, &maindata);
  519.         break;
  520.           } break;
  521.         case 2:                    // Settings
  522.           args->createicons =
  523.           ItemAddress(menus, (ULONG) Long)->Flags & CHECKED;
  524.           break;
  525.         }
  526.         Long = (ULONG) ItemAddress(menus, (ULONG) Long)->NextSelect;
  527.       } break;
  528.     case IDCMP_GADGETUP:
  529.       switch(GADGET(IntuiMessagePtr)->GadgetID)
  530.       {
  531.       case STRING_TypeName:
  532.         txt = STRINF(GADGET(IntuiMessagePtr))->Buffer;
  533.         FreeListView();
  534.         CopyMem(txt, maindata.ld_curNode->pn_TypeName, TypeSIZE);
  535.         ResetListView(~0, &maindata);
  536.         break;
  537.       case LISTVIEW: ResetListView(IntuiMessagePtr->Code, &maindata); break;
  538.       case BUTTON_New:
  539.         FreeListView();
  540.         if(!NewPackerNode(&maindata, text[TEXT_ENTRY_NEW],
  541.         DEFNODE(&maindata), maindata.ld_curNumber))
  542.           End(RETURN_FAIL);
  543.         ResetListView(~0, &maindata); break;
  544.       case BUTTON_Delete:
  545.         if(maindata.ld_curNumber)
  546.         {
  547.           FreeListView();
  548.           Remove((struct Node *) maindata.ld_curNode);
  549.           FreeMem(maindata.ld_curNode, sizeof(struct PackerNode));
  550.           if(--maindata.ld_entries == maindata.ld_curNumber)
  551.             --maindata.ld_curNumber;
  552.           ResetListView(~0, &maindata);
  553.         } break;
  554.       case BUTTON_Up:
  555.         if(maindata.ld_curNumber > 1)
  556.         {
  557.           struct Node *p;
  558.           FreeListView();
  559.           p = maindata.ld_curNode->pn_Node.ln_Pred->ln_Pred;
  560.           Remove((struct Node *) maindata.ld_curNode);
  561.           Insert(&maindata.ld_List, (struct Node *) maindata.ld_curNode, p);
  562.           ResetListView(--maindata.ld_curNumber, &maindata);
  563.         } break;
  564.       case BUTTON_Down:
  565.         if(maindata.ld_curNumber &&
  566.         maindata.ld_curNumber != maindata.ld_entries - 1)
  567.         {
  568.           struct Node *p;
  569.           FreeListView();
  570.           p = maindata.ld_curNode->pn_Node.ln_Succ;
  571.           Remove((struct Node *) maindata.ld_curNode);
  572.           Insert(&maindata.ld_List, (struct Node *) maindata.ld_curNode, p);
  573.           ResetListView(++maindata.ld_curNumber, &maindata);
  574.         } break;
  575.       case STRING_NamePatt:
  576.         txt = STRINF(GADGET(IntuiMessagePtr))->Buffer;
  577. // test if correct pattern
  578.         CopyMem(txt, &maindata.ld_curNode->pn_NamePattern, NamePattSIZE);
  579.         break;
  580.       case STRING_FilePatt:
  581.         txt = STRINF(GADGET(IntuiMessagePtr))->Buffer;
  582. // test if correct pattern
  583.         CopyMem(txt, &maindata.ld_curNode->pn_FilePattern, FilePattSIZE);
  584.         break;
  585.       case GETIMAGE: FileReq(); GT_SetGadgetAttrs(gadgdata[3], window,
  586.         0, GTST_String, &maindata.ld_curNode->pn_StdID, GA_Disabled,
  587.         maindata.ld_curNode->pn_Cycle, TAG_DONE);
  588.         break;
  589.       case STRING_LibraryName:
  590.         txt = STRINF(GADGET(IntuiMessagePtr))->Buffer;
  591.         if((Long = SDIConvToUpper(txt)))
  592.         {
  593.           maindata.ld_curNode->pn_StdID = Long;
  594.           GT_SetGadgetAttrs(gadgdata[3], window,
  595.           0, GTST_String, &maindata.ld_curNode->pn_StdID, GA_Disabled,
  596.           maindata.ld_curNode->pn_Cycle, TAG_DONE);
  597.         }
  598.         else
  599.         {
  600.           DisplayBeep(Scr);
  601.           ActivateGadget(GADGET(IntuiMessagePtr), window,0);
  602.         }
  603.         break;
  604.       case INTEGER_Mode:
  605.         Long = STRINF(GADGET(IntuiMessagePtr))->LongInt;
  606.         if((Long > 100) || (Long < 0))
  607.         {
  608.           DisplayBeep(Scr);
  609.           ActivateGadget(GADGET(IntuiMessagePtr), window,0);
  610.         }
  611.         else maindata.ld_curNode->pn_Mode = Long;
  612.         break;
  613.       case INTEGER_ChunkSize:
  614.         Long = STRINF(GADGET(IntuiMessagePtr))->LongInt;
  615.         if(Long < 0)
  616.         {
  617.           DisplayBeep(Scr);
  618.           ActivateGadget(GADGET(IntuiMessagePtr), window,0);
  619.         }
  620.         else maindata.ld_curNode->pn_ChunkSize = Long;
  621.         break;
  622.       case CYCLE: maindata.ld_curNode->pn_Cycle = IntuiMessagePtr->Code;
  623.         ResetListView(~0, &maindata); break;
  624.       case INTEGER_TimeOut:
  625.         Long = STRINF(GADGET(IntuiMessagePtr))->LongInt;
  626.         if(Long < 0 || Long > 0xFFFF)
  627.         {
  628.           DisplayBeep(Scr);
  629.           ActivateGadget(GADGET(IntuiMessagePtr), window,0);
  630.         }
  631.         else TimeOut = Long;
  632.         break;
  633.       case CHECKBOX_XFD:
  634.         XPKM_Flags ^= XPKM_UseXFD; break;
  635.       case CHECKBOX_EXT:
  636.         XPKM_Flags ^= XPKM_UseExternals; break;
  637.       case CHECKBOX_Password:
  638.         XPKM_Flags ^= XPKM_AutoPassword; break;
  639.       case BUTTON_Save:
  640.         if(!SaveFile((STRPTR) 1, 0))
  641.           if(!SaveFile(0, 0))
  642.         run = 0;
  643.          break;
  644.       case BUTTON_Use: if(!SaveFile(0, 0)) run = 0; break;
  645.       case BUTTON_Chancel: run = 0; break;
  646.       } break;
  647.     }
  648.         GT_ReplyIMsg(IntuiMessagePtr);
  649.       }
  650.   }
  651.   while(run);
  652. }
  653.  
  654. ULONG SDIConvToUpper(STRPTR b)
  655. {
  656.   ULONG i;
  657.   ULONG out = 0;
  658.  
  659.   for(i = 0; i < 4; ++i)
  660.   {
  661.     if(!SDI_isalnum(b[i]))
  662.       return 0;
  663.     out = (out<<8) + SDI_toupper(b[i]);
  664.   }
  665.  
  666.   return out;
  667. }
  668.  
  669. /* ----------------------- loading functions --------------------------- */
  670.  
  671. void CorrectAdr(APTR pos, APTR mempos)
  672. { // changes relative addresses into normal ones
  673.   if(*(ULONG *)pos)
  674.     *(ULONG *)pos += (ULONG) mempos;
  675. }
  676.  
  677. void CopyStrings(STRPTR from, STRPTR to, ULONG Size)
  678. {
  679.   ULONG i;
  680.  
  681.   if(from)
  682.   {
  683.     if((i = SDI_strlen(from)) > Size)
  684.       i = Size;
  685.     CopyMem(from, to, i);
  686.   }
  687. }
  688.  
  689. void CopyLibName(struct XpkTypeData *p, struct PackerNode *n)
  690. {
  691.   if(p->xtd_Flags & XTD_NoPack)
  692.     n->pn_Cycle = 1;
  693.   else if(p->xtd_Flags & XTD_ReturnError || !p->xtd_StdID)
  694.     n->pn_Cycle = 2;
  695.   else
  696.   {
  697.     n->pn_Cycle = 0;
  698.     n->pn_StdID = p->xtd_StdID;
  699.   }
  700. }
  701.  
  702. void ReadXPKM(struct XpkMainPrefs *pref, struct ListData *dat)
  703. {
  704.   struct PackerNode *n = DEFNODE(dat);
  705.   struct XpkTypeData *p;
  706.  
  707.   CorrectAdr(&pref->xmp_DefaultType, pref);
  708.   p = pref->xmp_DefaultType;
  709.   CopyLibName(p, n);
  710.   n->pn_Mode = p->xtd_Mode;
  711.   n->pn_ChunkSize = p->xtd_ChunkSize;
  712.   TimeOut = pref->xmp_Timeout;
  713.   XPKM_Flags = pref->xmp_Flags;
  714. }
  715.  
  716. ULONG ReadXPKT(struct XpkTypePrefs *pref, struct ListData *dat)
  717. {
  718.   struct PackerNode *n;
  719.  
  720.   CorrectAdr(&pref->xtp_NamePattern, pref);
  721.   CorrectAdr(&pref->xtp_FilePattern, pref);
  722.   CorrectAdr(&pref->xtp_TypeName, pref);
  723.   CorrectAdr(&pref->xtp_PackerData, pref);
  724.   if(!pref->xtp_TypeName)
  725.     pref->xtp_TypeName = text[TEXT_ENTRY_NEW];
  726.  
  727.   if(!(n = NewPackerNode(dat, pref->xtp_TypeName, 0, dat->ld_curNumber)))
  728.     return 2;
  729.  
  730.   CopyStrings(pref->xtp_NamePattern, n->pn_NamePattern, NamePattSIZE);
  731.   CopyStrings(pref->xtp_FilePattern, n->pn_FilePattern, FilePattSIZE);
  732.   CopyLibName(pref->xtp_PackerData, n);
  733.   n->pn_Mode = pref->xtp_PackerData->xtd_Mode;
  734.   n->pn_ChunkSize = pref->xtp_PackerData->xtd_ChunkSize;
  735.   return 0;
  736. }
  737.  
  738. ULONG LoadFile(STRPTR file, ULONG addmode)
  739. {
  740. // addmode only processes PRHD and XPKT chunks (not XPKM) -- adds the
  741. // chunks to the list -- no replacement
  742.  
  743.   struct ContextNode  *cn;
  744.   struct IFFHandle *iff;
  745.   ULONG data = (ULONG) file > 1 ? 1 : 0;
  746.   ULONG error = 0;
  747.  
  748.   if(file == (STRPTR) 1)
  749.     file = "ENVARC:xpkmaster.prefs";
  750.   else if(!file)
  751.     file = "ENV:xpkmaster.prefs";
  752.  
  753.   if((iff = AllocIFF()))
  754.   {
  755.     if((iff->iff_Stream = Open(file, MODE_OLDFILE)))
  756.     {
  757.       InitIFFasDOS(iff);
  758.       if(!(error = OpenIFF(iff, IFFF_READ)))
  759.       {
  760.     LONG a[] = { ID_PREF, ID_PRHD, ID_PREF, ID_XPKT, ID_PREF, ID_XPKM};
  761.     if(!(error = StopChunks(iff, a, 3)))
  762.     {
  763.       STRPTR buf;
  764.       ULONG Flags = (addmode ? 2 : 0);
  765.  
  766.       while(!error)
  767.           {
  768.             if((error = ParseIFF(iff,IFFPARSE_SCAN)))
  769.               break;
  770.  
  771.             cn = CurrentChunk(iff);
  772.  
  773.         if(!addmode && cn->cn_ID != ID_PRHD)
  774.         {    // clear list only when XPKT or XPKM and not addmode
  775.           NewPackerList(&maindata); addmode = 1;
  776.         }
  777.  
  778.         if((buf = (STRPTR) AllocMem(cn->cn_Size, MEMF_ANY|MEMF_CLEAR)))
  779.         {
  780.           ReadChunkBytes(iff,buf,cn->cn_Size);
  781.           switch(cn->cn_ID)
  782.           {
  783.           case ID_PRHD:
  784.         if(!(Flags & 1))
  785.         {
  786.           if(((struct PrefHeader *) buf)->ph_Version > PREF_VERSION)
  787.             PrintError(text[TEXT_VERSION_TO_HIGH]);
  788.           Flags |= 1;
  789.         } break;
  790.           case ID_XPKM:
  791.         if(!(Flags & 2))
  792.         {
  793.           ReadXPKM((struct XpkMainPrefs *) buf, &maindata);
  794.           Flags |= 2;
  795.         } break;
  796.           case ID_XPKT:
  797.         error = ReadXPKT((struct XpkTypePrefs *) buf, &maindata);
  798.         break;
  799.           }
  800.           FreeMem(buf, cn->cn_Size);
  801.         }
  802.         else error = 2;
  803.       }
  804.       if(error == IFFERR_EOF)
  805.         error = 0;
  806.     }
  807.         CloseIFF(iff);
  808.       }
  809.       Close(iff->iff_Stream);
  810.     }
  811.     else if(data)
  812.     {
  813.       UBYTE err[100];
  814.       Fault(IoErr(), 0, err, 100);
  815.       PrintError(text[TEXT_ERROR_FILEACCESS], file, &err);
  816.       error = 1;
  817.     }
  818.     else
  819.       error = 1;
  820.     FreeIFF(iff);
  821.   }
  822.  
  823.   if(error && error != 1)
  824.     PrintError(text[TEXT_ERROR_FILEPROCESS]);
  825.  
  826.   return error;
  827. }
  828.  
  829. /* ----------------------- saving functions ---------------------------- */
  830.  
  831. ULONG CopyData(STRPTR from, ULONG *to, APTR data, STRPTR *entry)
  832. {
  833.   ULONG i = SDI_strlen(from);
  834.  
  835.   if(!(*from))
  836.     return 0;
  837.   CopyMem(from, (STRPTR) data + *to, i);
  838.   *entry = (STRPTR) *to;
  839.   *to += ++i;
  840. }
  841.  
  842. #define XPKM_Size    (sizeof(struct XpkMainPrefs) + \
  843.             sizeof(struct XpkTypeData))
  844.  
  845. #define    xpkm    ((struct XpkMainPrefs *) data)
  846. #define xpkd    ((struct XpkTypeData *) (data + sizeof(struct XpkMainPrefs)))
  847.  
  848. ULONG WriteXPKM(struct IFFHandle *iff)
  849. {
  850.   STRPTR data;
  851.   struct PackerNode *r = DEFNODE(&maindata);
  852.   ULONG ptr = sizeof(struct XpkMainPrefs), error;
  853.  
  854.   if(!r->pn_Cycle && !r->pn_StdID)
  855.   {
  856.     PrintError(text[TEXT_ILLEGAL_ENTRY], text[GADG_Library_Name], 1, r->pn_TypeName);
  857.     return 1;
  858.   }
  859.  
  860.   if((data = (STRPTR) AllocMem(XPKM_Size, MEMF_ANY|MEMF_CLEAR)))
  861.   {
  862. //    xpkm->xmp_Version        = 0;    /* structure version */
  863.     xpkm->xmp_Flags        = XPKM_Flags;
  864.     xpkm->xmp_Timeout        = TimeOut;
  865.     xpkm->xmp_DefaultType    = (struct XpkTypeData *) ptr;
  866.     ptr += sizeof(struct XpkTypeData);
  867.  
  868.     switch(r->pn_Cycle)
  869.     {
  870.     case 0:
  871.       xpkd->xtd_Mode = r->pn_Mode;
  872.       xpkd->xtd_ChunkSize = r->pn_ChunkSize;
  873.       xpkd->xtd_StdID = r->pn_StdID;
  874.       break;
  875.     case 1: xpkd->xtd_Flags |= XTD_NoPack; break;
  876.     case 2: xpkd->xtd_Flags |= XTD_ReturnError; break;
  877.     }
  878.  
  879.     if(!(error = PushChunk(iff, 0, ID_XPKM, ptr)))
  880.     {
  881.       if(WriteChunkBytes(iff, data, ptr) != ptr)
  882.     error = 3;
  883.       else
  884.     error = PopChunk(iff);
  885.     }
  886.     FreeMem(data, XPKM_Size);
  887.   }
  888.   else
  889.     error = 2;
  890.  
  891.   return error;
  892. }
  893.  
  894. #define xpkt        ((struct XpkTypePrefs *) data)
  895. #define xtd        ((struct XpkTypeData *) (data + sizeof(struct XpkTypePrefs)))
  896.  
  897. #define XPKT_Size    (TypeSIZE + 1 + NamePattSIZE + 1 + \
  898.             FilePattSIZE + 1 + sizeof(struct XpkTypePrefs)) \
  899.             + sizeof(struct XpkTypeData)
  900.  
  901. ULONG WriteXPKT(struct IFFHandle *iff, struct PackerNode *r, ULONG num)
  902. {
  903.   STRPTR data;
  904.   ULONG error, ptr = sizeof(struct XpkTypePrefs) + sizeof(struct XpkTypeData);
  905.  
  906.   if(!r->pn_Cycle && !r->pn_StdID)
  907.   {
  908.     PrintError(text[TEXT_ILLEGAL_ENTRY], text[GADG_Library_Name], num+1, r->pn_TypeName);
  909.     return 1;
  910.   }
  911.   else if(!r->pn_NamePattern[0] && !r->pn_FilePattern[0])
  912.   {
  913.     PrintError(text[TEXT_ILLEGAL_ENTRY], text[GADG_File_Pattern], num+1, r->pn_TypeName);
  914.     return 1;
  915.   }
  916.  
  917.   if((data = (STRPTR) AllocMem(XPKT_Size, MEMF_ANY|MEMF_CLEAR)))
  918.   {
  919.     if(CopyData(r->pn_NamePattern, &ptr, data, &xpkt->xtp_NamePattern))
  920.       xpkt->xtp_Flags |= XPKT_NamePattern;
  921.     if(CopyData(r->pn_FilePattern, &ptr, data, &xpkt->xtp_FilePattern))
  922.       xpkt->xtp_Flags |= XPKT_FilePattern;
  923.     CopyData(r->pn_TypeName, &ptr, data, &xpkt->xtp_TypeName);
  924.     xpkt->xtp_PackerData = (struct XpkTypeData *) sizeof(struct XpkTypePrefs);
  925.  
  926.     switch(r->pn_Cycle)
  927.     {
  928.     case 0:
  929.       xtd->xtd_Mode = r->pn_Mode;
  930.       xtd->xtd_ChunkSize = r->pn_ChunkSize;
  931.       xtd->xtd_StdID = r->pn_StdID;
  932.       break;
  933.     case 1: xtd->xtd_Flags |= XTD_NoPack; break;
  934.     case 2: xtd->xtd_Flags |= XTD_ReturnError; break;
  935.     }
  936.  
  937.     if(!(error = PushChunk(iff, 0, ID_XPKT, ptr)))
  938.     {
  939.       if(WriteChunkBytes(iff, data, ptr) != ptr)
  940.     error = 3;
  941.       else
  942.     error = PopChunk(iff);
  943.     }
  944.     FreeMem(data, XPKT_Size);
  945.   }
  946.   else
  947.     error = 2;
  948.  
  949.   return error;
  950. }
  951.  
  952. ULONG SaveFile(STRPTR file, ULONG icons)
  953. {
  954.   struct IFFHandle *iff;
  955.   ULONG error = 0;
  956.  
  957.   if(file == (STRPTR) 1)
  958.     file = "ENVARC:xpkmaster.prefs";
  959.   else if(!file)
  960.     file = "ENV:xpkmaster.prefs";
  961.  
  962.   if((iff = AllocIFF()))
  963.   {
  964.     if((iff->iff_Stream = Open(file, MODE_NEWFILE)))
  965.     {
  966.       InitIFFasDOS(iff);
  967.       if(!(error = OpenIFF(iff, IFFF_WRITE)))
  968.       {
  969.         if(!(error = PushChunk(iff, ID_PREF, ID_FORM, IFFSIZE_UNKNOWN)))
  970.         {
  971.           if(!(error = PushChunk(iff, 0, ID_PRHD, sizeof(struct PrefHeader))))
  972.           {
  973.         struct PrefHeader a = {PREF_VERSION, 0, 0};
  974.         if(WriteChunkBytes(iff, &a, sizeof(struct PrefHeader))
  975.         == sizeof(struct PrefHeader))
  976.         {
  977.           if(!(error = PopChunk(iff)))
  978.           {
  979.             if(!(error = WriteXPKM(iff)))
  980.             {
  981.           struct Node *n = FindNode(&maindata.ld_List, 1);
  982.           ULONG num = 1, a;
  983.           for(a = maindata.ld_entries-1; a; --a)
  984.           {
  985.             if((error = WriteXPKT(iff, (struct PackerNode *) n, num)))
  986.               break;
  987.             n = n->ln_Succ; ++num;
  988.           }
  989.             }
  990.           }
  991.         }
  992.         else
  993.           error = 2;
  994.       }
  995.       if(!error)
  996.         error = PopChunk(iff);
  997.     }
  998.         CloseIFF(iff);
  999.       }
  1000.       Close(iff->iff_Stream);
  1001.       if(error)
  1002.           DeleteFile(file);
  1003.     }
  1004.     else
  1005.     {
  1006.       UBYTE err[100];
  1007.       Fault(IoErr(), 0, err, 100);
  1008.       PrintError(text[TEXT_ERROR_FILEACCESS], file, &err);
  1009.       error = 1;
  1010.     }
  1011.     FreeIFF(iff);
  1012.   }
  1013.  
  1014.   if(!error && icons)
  1015.   {
  1016.     ULONG i = SDI_strlen(file);
  1017.     STRPTR a;
  1018.  
  1019.     if((a = (STRPTR) AllocMem(i+1+5, MEMF_ANY)))
  1020.     {
  1021.       ULONG fh;
  1022.  
  1023.       CopyMem(file, a, i);
  1024.       CopyMem(".info", a+i, 6);
  1025.       if((fh = Open(a, MODE_NEWFILE)))
  1026.       {
  1027.     Write(fh, PicData, PicSize);
  1028.     Close(fh);
  1029.       }
  1030.       FreeMem(a, i+1+5);
  1031.     }
  1032.   }
  1033.  
  1034.   if(error && error != 1)
  1035.     PrintError(text[TEXT_ERROR_FILEPROCESS]);
  1036.  
  1037.   return error;
  1038. }
  1039.  
  1040. /* ---------------------- graphics functions --------------------------- */
  1041.  
  1042. void PrintError(STRPTR txt, ...)
  1043. {
  1044.   struct EasyStruct easystruct;
  1045.  
  1046.   SDI_memset(&easystruct, 0, sizeof(struct EasyStruct));
  1047.  
  1048.   easystruct.es_StructSize = sizeof(struct EasyStruct);
  1049.   easystruct.es_Title = text[TEXT_TITLE_ERR_REQUEST];
  1050.   easystruct.es_TextFormat = txt;
  1051.   easystruct.es_GadgetFormat = text[GADGS_ERR_REQUEST];
  1052.  
  1053.   EasyRequestArgs(window, &easystruct, 0, (APTR)
  1054.   ((ULONG) &txt + sizeof(STRPTR)));
  1055. }
  1056.  
  1057. void FileReq(void)
  1058. {
  1059.   ULONG Long;
  1060.   UBYTE libname[] = "x..____.library";
  1061.   struct FileRequester *r;
  1062.  
  1063.   CopyMem(&maindata.ld_curNode->pn_StdID, libname+3, 4);
  1064.   if(libname[3] == 'X')
  1065.   {
  1066.     libname[1] = 'e'; libname[2] = 'x';
  1067.   }
  1068.   else
  1069.   {
  1070.     libname[1] = 'p'; libname[2] = 'k';
  1071.   }
  1072.  
  1073.   if((AslBase = OpenLibrary("asl.library", 37)))
  1074.   {
  1075.     if((r = (struct FileRequester *) AllocAslRequest(ASL_FileRequest, 0)))
  1076.     {
  1077.       if((AslRequestTags(r, ASLFR_TitleText, text[TEXT_SELECT_LIBRARY],
  1078.     ASLFR_InitialFile, libname,
  1079.     ASLFR_InitialDrawer, "LIBS:compressors", ASLFR_DoSaveMode, FALSE,
  1080.     ASLFR_InitialPattern, "(xpk|xex)????.library", TAG_DONE)))
  1081.         if((!SDI_strncmp(r->fr_File, "xpk", 3) ||
  1082.         !SDI_strncmp(r->fr_File, "xex", 3) &&
  1083.         !SDI_strcmp(r->fr_File+7, ".library")) &&
  1084.         (Long = SDIConvToUpper(r->fr_File+3)))
  1085.       maindata.ld_curNode->pn_StdID = Long;
  1086.     else
  1087.       DisplayBeep(Scr);
  1088.       FreeAslRequest(r);
  1089.     }
  1090.     CloseLibrary(AslBase);
  1091.     AslBase = 0;
  1092.   }
  1093.   else
  1094.     PrintError(text[TEXT_LIB_REQUIRED], "asl.library", 37);
  1095. }
  1096.  
  1097. ULONG PrefsFileReq(STRPTR dir, ULONG mode, STRPTR title)
  1098. {
  1099.   ULONG error = 0;
  1100.   struct FileRequester *r;
  1101.  
  1102.   if((AslBase = OpenLibrary("asl.library", 37)))
  1103.   {
  1104.     if((r = (struct FileRequester *) AllocAslRequest(ASL_FileRequest, 0)))
  1105.     {
  1106.       UBYTE d[200], *f = 0;
  1107.  
  1108.       if(dir)
  1109.       {
  1110.         CopyMem(dir, d, 200);
  1111.         if((f = FilePart(dir)))
  1112.         d[f-dir] = 0;
  1113.       }
  1114.       
  1115.       if((AslRequestTags(r, ASLFR_TitleText, title,
  1116.     ASLFR_InitialDrawer, dir ? d : "SYS:Prefs/Presets",
  1117.     ASLFR_DoSaveMode, mode,    (f ? ASLFR_InitialFile : TAG_DONE), f,
  1118.     TAG_DONE)))
  1119. // only give ASLFR_InitialFile, when f is not zero, because else
  1120. // asl.library makes Enforcer hit!
  1121.       {
  1122.         CopyMem(r->fr_Drawer, namestring, SDI_strlen(r->fr_Drawer)+1);
  1123.         AddPart(namestring, r->fr_File, 256);
  1124.         error = 1;
  1125.       }
  1126.       FreeAslRequest(r);
  1127.     }
  1128.     CloseLibrary(AslBase);
  1129.     AslBase = 0;
  1130.   }
  1131.   else
  1132.     PrintError(text[TEXT_LIB_REQUIRED], "asl.library", 37);
  1133.  
  1134.   return error;
  1135. }
  1136.  
  1137. void FreeListView(void)
  1138. {
  1139.   GT_SetGadgetAttrs(gadgdata[0], window, 0, GTLV_Labels, ~0, TAG_DONE);
  1140. }
  1141.  
  1142. void ResetListView(ULONG number, struct ListData *dat)
  1143. {
  1144.   STRPTR lib = "";
  1145.  
  1146.   if(number == ~0)
  1147.     number = dat->ld_curNumber;
  1148.   dat->ld_curNode = (struct PackerNode *) FindNode(&dat->ld_List, number);
  1149.  
  1150.   // NamePattern
  1151.   GT_SetGadgetAttrs(gadgdata[1], window, 0, GTST_String,
  1152.   dat->ld_curNode->pn_NamePattern, GA_Disabled, !number, TAG_DONE);
  1153.  
  1154.   // FilePattern
  1155.   GT_SetGadgetAttrs(gadgdata[2], window, 0, GTST_String,
  1156.   dat->ld_curNode->pn_FilePattern, GA_Disabled, !number, TAG_DONE);
  1157.  
  1158.   // Cycle
  1159.   GT_SetGadgetAttrs(gadgdata[7], window, 0, GTCY_Active,
  1160.   dat->ld_curNode->pn_Cycle, TAG_DONE);
  1161.  
  1162.   // Listview
  1163.   GT_SetGadgetAttrs(gadgdata[0], window, 0, GTLV_Labels, &dat->ld_List,
  1164.   GTLV_Selected, number, GTLV_Top, ((LONG) number - 5 < 0 ?
  1165.   0 : number - 5), TAG_DONE);
  1166.  
  1167.   if(dat->ld_curNode->pn_StdID)
  1168.     lib = (STRPTR) &dat->ld_curNode->pn_StdID;
  1169.  
  1170.   // Name
  1171.   GT_SetGadgetAttrs(gadgdata[3], window, 0, GTST_String,
  1172.   lib, GA_Disabled, dat->ld_curNode->pn_Cycle, TAG_DONE);
  1173.  
  1174.   // GetImage
  1175.   GT_SetGadgetAttrs(gadgdata[4], window, 0, GA_Disabled,
  1176.   dat->ld_curNode->pn_Cycle, TAG_DONE);
  1177.  
  1178.   // Mode
  1179.   GT_SetGadgetAttrs(gadgdata[5], window, 0, GTIN_Number,
  1180.   dat->ld_curNode->pn_Mode, GA_Disabled, dat->ld_curNode->pn_Cycle,
  1181.   TAG_DONE);
  1182.  
  1183.   // ChunkSize
  1184.   GT_SetGadgetAttrs(gadgdata[6], window, 0, GTIN_Number,
  1185.   dat->ld_curNode->pn_ChunkSize, GA_Disabled, dat->ld_curNode->pn_Cycle,
  1186.   TAG_DONE);
  1187.  
  1188.   dat->ld_curNumber = number;
  1189. }
  1190.  
  1191. void SetMainData(void)
  1192. {
  1193.   ULONG i;
  1194.  
  1195.   for(i = 0; i < 3; i++)
  1196.   {
  1197.     GT_SetGadgetAttrs(gadgdata[9+i], window, 0, GTCB_Checked,
  1198.     XPKM_Flags & (1<<i), TAG_DONE);
  1199.   }
  1200.   GT_SetGadgetAttrs(gadgdata[8], window, 0, GTIN_Number, TimeOut, TAG_DONE);
  1201. }
  1202.  
  1203. ULONG DoWindow(void)
  1204. {
  1205.   UWORD    winwidth, winheight;
  1206.   STRPTR *txt = text + GADG_New;
  1207.   ULONG i, j, k;
  1208.   struct Gadget        *g;
  1209.   struct NewGadget    ng;
  1210.  
  1211.   SDI_memset(&ng, 0, sizeof(struct NewGadget));
  1212.  
  1213.   ng.ng_LeftEdge = Scr->WBorLeft + SEPARATE_BORD;
  1214.   ng.ng_TopEdge = Scr->WBorTop + Scr->Font->ta_YSize + 1 + SEPARATE_BORD;
  1215.   ng.ng_Height = Scr->Font->ta_YSize+5;
  1216.   ng.ng_TextAttr = Scr->Font;
  1217.   ng.ng_GadgetID = 100;
  1218.   ng.ng_VisualInfo = VisualInfo;
  1219.  
  1220.   if(!(g = CreateContext(&gadgList)))
  1221.     return 1;
  1222.  
  1223.   for(i = k = 0; i < 4; ++i)
  1224.   {
  1225.     ng.ng_Width = 7 + TextLength(&Scr->RastPort, txt[i], SDI_strlen(txt[i]));
  1226.     if(ng.ng_Width > k)
  1227.       k = ng.ng_Width;
  1228.   }
  1229.   ng.ng_Width = k << 2;
  1230.  
  1231.   if(!(g = CreateGadget(STRING_KIND, g, &ng, GTST_MaxChars, TypeSIZE, TAG_DONE)))
  1232.     return 2;
  1233.   ++ng.ng_GadgetID;
  1234.  
  1235.   ng.ng_Height *= 10;
  1236.  
  1237.   if(!(gadgdata[0] = g = CreateGadget(LISTVIEW_KIND,g,&ng,
  1238.   GTLV_ShowSelected, g, TAG_DONE)))
  1239.     return 3;
  1240.  
  1241.   ++ng.ng_GadgetID;
  1242.   ng.ng_LeftEdge = Scr->WBorLeft + SEPARATE_BORD;
  1243.   ng.ng_TopEdge += g->Height + Scr->Font->ta_YSize+5;
  1244.   ng.ng_Height = Scr->Font->ta_YSize+5;
  1245.   ng.ng_Flags = PLACETEXT_IN;
  1246.   ng.ng_Width = k;
  1247.  
  1248.   for(i = 0; i < 4; ++i)
  1249.   {
  1250.     ng.ng_GadgetText = *(txt++);
  1251.     if(!(g = CreateGadgetA(BUTTON_KIND, g, &ng, 0)))
  1252.       return 4;
  1253.     ++ng.ng_GadgetID;
  1254.     ng.ng_LeftEdge += ng.ng_Width;
  1255.   }
  1256.  
  1257.   winheight = ng.ng_TopEdge + ng.ng_Height + SEPARATE_DIFF;
  1258.  
  1259.   ng.ng_TopEdge = Scr->WBorTop + Scr->Font->ta_YSize + 1 + SEPARATE_BORD;
  1260.   txt = text + GADG_Name_Pattern;
  1261.  
  1262.   for(i = k = 0; i < 6; ++i)
  1263.   {
  1264.     j = 7 + TextLength(&Scr->RastPort, txt[i], SDI_strlen(txt[i]));
  1265.     if(j > k)
  1266.       k = j;
  1267.   }
  1268.  
  1269.   j = ng.ng_LeftEdge + SEPARATE_DIFF; /* store startpos */
  1270.   ng.ng_LeftEdge = j + k;
  1271.  
  1272.   ng.ng_Width = 0;
  1273.   for(i = 0; i < 3; ++i)
  1274.   {
  1275.     STRPTR *tx = text + TEXT_START_SLIDER;
  1276.     k = 50 + TextLength(&Scr->RastPort, tx[i], SDI_strlen(tx[i]));
  1277.     if(k > ng.ng_Width)
  1278.       ng.ng_Width = k;
  1279.   } /* width of gadgets is the one of the cycle gadget */
  1280.  
  1281.   ng.ng_Flags = PLACETEXT_LEFT;
  1282.   winwidth = ng.ng_LeftEdge + ng.ng_Width; /* set resulting window width */
  1283.  
  1284.   for(i = 0; i < 2; ++i)
  1285.   {
  1286.     ng.ng_GadgetText = *(txt++);
  1287.     if(!(gadgdata[i+1] = g = CreateGadget(STRING_KIND,g,&ng, GTST_MaxChars,
  1288.     (i ? FilePattSIZE : NamePattSIZE), TAG_DONE)))
  1289.       return 5;
  1290.     ++ng.ng_GadgetID;
  1291.     ng.ng_TopEdge += ng.ng_Height + SEPARATE_SAME;
  1292.   }
  1293.  
  1294.   ng.ng_Width -= ng.ng_Height;
  1295.   ng.ng_GadgetText = *(txt++);
  1296.   if(!(gadgdata[3] = g = CreateGadget(STRING_KIND,g,&ng, GTST_MaxChars, 4,
  1297.   STRINGA_Justification, GACT_STRINGCENTER, TAG_DONE)))
  1298.     return 6;
  1299.   ++ng.ng_GadgetID;
  1300.   ng.ng_GadgetText = 0;
  1301.   k = ng.ng_Width;
  1302.   ng.ng_Width = ng.ng_Height;
  1303.   ng.ng_LeftEdge += k;
  1304.   if(!(gadgdata[4] = g = CreateGadgetA(BUTTON_KIND,g,&ng, 0)))
  1305.     return 7;
  1306.   ng.ng_LeftEdge -= k;
  1307.   ng.ng_Width += k;
  1308.   ++ng.ng_GadgetID;
  1309.   ng.ng_TopEdge += ng.ng_Height + SEPARATE_SAME;
  1310.  
  1311.   for(i = 0; i < 2; ++i)
  1312.   {
  1313.     ng.ng_GadgetText = *(txt++);
  1314.     if(!(gadgdata[i+5] = g = CreateGadget(INTEGER_KIND,g,&ng, 
  1315.     STRINGA_Justification, GACT_STRINGCENTER, TAG_DONE)))
  1316.       return 8;
  1317.     ++ng.ng_GadgetID;
  1318.     ng.ng_TopEdge += ng.ng_Height + SEPARATE_SAME;
  1319.   }
  1320.  
  1321.   ng.ng_GadgetText = *txt;
  1322.  
  1323.   if(!(gadgdata[7] = g = CreateGadget(CYCLE_KIND,g,&ng, GTCY_Labels,
  1324.   text + TEXT_START_SLIDER, TAG_DONE)))
  1325.       return 9;
  1326.  
  1327.   ++ng.ng_GadgetID;
  1328.   ng.ng_TopEdge += ng.ng_Height + SEPARATE_DIFF;
  1329.   txt = text + GADG_Use_XFD;
  1330.   ng.ng_LeftEdge = j;
  1331.  
  1332.   for(i = k = 0; i < 3; ++i)
  1333.   {
  1334.     ng.ng_Width = 50 + TextLength(&Scr->RastPort, txt[i], SDI_strlen(txt[i]));
  1335.     if(ng.ng_Width > k)
  1336.       k = ng.ng_Width;
  1337.   }
  1338.  
  1339.   ng.ng_GadgetText = txt[3];
  1340.   ng.ng_LeftEdge += k + ng.ng_Height;
  1341.   if((ng.ng_Width = 7 + TextLength(&Scr->RastPort, txt[3],
  1342.   SDI_strlen(txt[3]))) < Scr->RastPort.TxWidth << 3)
  1343.     ng.ng_Width = Scr->RastPort.TxWidth << 3;
  1344.   ng.ng_Flags = PLACETEXT_BELOW;
  1345.   if(!(gadgdata[8] = g = CreateGadget(INTEGER_KIND,g,&ng, GTIN_MaxChars, 5, STRINGA_Justification,
  1346.   GACT_STRINGCENTER, TAG_DONE)))
  1347.       return 10;
  1348.   ++ng.ng_GadgetID;
  1349.   ng.ng_LeftEdge -= k + ng.ng_Height;
  1350.   ng.ng_Width = ng.ng_Height;
  1351.   ng.ng_Flags = PLACETEXT_RIGHT;
  1352.  
  1353.   for(i = 0; i < 3; ++i)
  1354.   {
  1355.     ng.ng_GadgetText = *(txt++);
  1356.     if(!(gadgdata[9+i] = g = CreateGadgetA(CHECKBOX_KIND,g,&ng,0)))
  1357.       return 11;
  1358.     ++ng.ng_GadgetID;
  1359.     ng.ng_TopEdge += ng.ng_Height;
  1360.   }
  1361.  
  1362.   if(winheight < ng.ng_TopEdge + 5)
  1363.     winheight = ng.ng_TopEdge + SEPARATE_DIFF;
  1364.  
  1365.   ng.ng_TopEdge = winheight;
  1366.   ng.ng_LeftEdge = Scr->WBorLeft + SEPARATE_BORD;
  1367.   ng.ng_Flags = PLACETEXT_IN;
  1368.   txt = text + GADG_Save;
  1369.  
  1370.   ng.ng_Width = 0;
  1371.   for(i = 0; i < 3; ++i)
  1372.   {
  1373.     k = 7 + TextLength(&Scr->RastPort, txt[i], SDI_strlen(txt[i]));
  1374.     if(k >ng.ng_Width)
  1375.       ng.ng_Width = k;
  1376.   }
  1377.   k = (winwidth - SEPARATE_BORD - 3*ng.ng_Width)/6;
  1378.   ng.ng_LeftEdge += k;
  1379.  
  1380.   for(i = 0; i < 3; ++i)
  1381.   {
  1382.     ng.ng_GadgetText = *(txt++);
  1383.     if(!(g = CreateGadgetA(BUTTON_KIND, g, &ng, 0)))
  1384.       return 12;
  1385.     ++ng.ng_GadgetID;
  1386.     ng.ng_LeftEdge += ng.ng_Width + (k<<1);
  1387.   }  
  1388.  
  1389.   winwidth += Scr->WBorRight + SEPARATE_BORD;
  1390.   winheight += Scr->WBorBottom + ng.ng_Height + SEPARATE_BORD;
  1391.  
  1392.   if(winwidth > Scr->Width || winheight > Scr->Height)
  1393.   {
  1394.     PrintError(text[TEXT_NO_WINDOW],0);
  1395.     return 20;
  1396.   }
  1397.  
  1398.   if(!(menus = CreateMenusA(NewMenus, 0)))
  1399.     return 21;
  1400.  
  1401.   LayoutMenus(menus, VisualInfo, GTMN_NewLookMenus, TRUE, TAG_DONE);
  1402.  
  1403.   if(!(window = OpenWindowTags(0,
  1404.     WA_Top,        Scr->BarHeight + 1,
  1405.     WA_Width,    winwidth,
  1406.     WA_Height,    winheight,
  1407.     WA_IDCMP,    IDCMP_GADGETUP|IDCMP_MENUPICK|IDCMP_GADGETDOWN|
  1408.             IDCMP_MOUSEMOVE|IDCMP_INTUITICKS|IDCMP_MOUSEBUTTONS,
  1409.     WA_Flags,    WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_SMART_REFRESH,
  1410.     WA_Gadgets,    gadgList,
  1411.     WA_Title,    text[TEXT_WINDOW_TITLE],
  1412.     WA_AutoAdjust,    TRUE,
  1413.         WA_Activate,    TRUE,
  1414.     WA_NewLookMenus,TRUE,
  1415.     WA_PubScreen,    Scr,
  1416.     TAG_DONE)))
  1417.     return 22;
  1418.  
  1419.   ResetListView(0, &maindata);
  1420.   SetMainData();
  1421.   SetMenuStrip(window, menus);
  1422.   GT_RefreshWindow(window,0);
  1423.   ScreenToFront(Scr);
  1424.  
  1425.   return 0;
  1426. }
  1427.  
  1428. /* --------------------------- list functions -------------------------- */
  1429.  
  1430. void NewPackerList(struct ListData *ld)
  1431. {
  1432.   if(ld->ld_entries)
  1433.     FreePackerList(ld);
  1434.   TimeOut = DEF_TIMEOUT; XPKM_Flags = DEF_XPKM_FLAGS;
  1435.   if(!NewPackerNode(&maindata, text[TEXT_ENTRY_DEFAULT], 0, 0))
  1436.     End(RETURN_FAIL);
  1437.   maindata.ld_curNode->pn_Cycle = DEF_CYCLE;
  1438. }
  1439.  
  1440. void FreePackerList(struct ListData *li)
  1441. {
  1442.   struct Node *n;
  1443.   while((n = RemHead(&li->ld_List)))
  1444.     FreeMem(n, sizeof(struct PackerNode));
  1445.   li->ld_curNumber = li->ld_entries = 0;
  1446.   li->ld_curNode = 0;
  1447. }
  1448.  
  1449. struct Node *FindNode(struct List *li, ULONG num)
  1450. {
  1451.   struct Node *n = li->lh_Head;
  1452.  
  1453.   ++num;
  1454.   if(n == (struct Node *) li)
  1455.     return 0;
  1456.   while(--num)
  1457.   {
  1458.     if(n == li->lh_TailPred)
  1459.       return 0;
  1460.     n = n->ln_Succ;
  1461.   }
  1462.   return n;
  1463. }
  1464.  
  1465. struct PackerNode *NewPackerNode(struct ListData *li, STRPTR name,
  1466. struct PackerNode *pref, ULONG mode)
  1467. {
  1468.   struct PackerNode *n;
  1469.   ULONG i;
  1470.  
  1471.   if(!(n = (struct PackerNode *) AllocMem(sizeof(struct PackerNode), MEMF_ANY|MEMF_CLEAR)))
  1472.     return 0;
  1473.  
  1474.   if(pref)
  1475.     CopyMem((STRPTR) pref + sizeof(struct Node), (STRPTR) n +
  1476.     sizeof(struct Node), sizeof(struct PackerNode) - sizeof(struct Node));
  1477.  
  1478.   n->pn_Node.ln_Name = n->pn_TypeName;
  1479.   n->pn_Node.ln_Type = mode ? PACKER_NODE : DEFAULT_NODE;
  1480.  
  1481.   if((i = SDI_strlen(name) + 1) > TypeSIZE)
  1482.     i = TypeSIZE;
  1483.   CopyMem(name, &n->pn_TypeName, i);
  1484.  
  1485.   if(li)
  1486.   {
  1487.     struct Node *p;
  1488.     if((p = FindNode(&li->ld_List, mode)))
  1489.     {
  1490.       Insert(&li->ld_List, (struct Node *) n, p);
  1491.       li->ld_curNumber = mode + 1;
  1492.     }
  1493.     else
  1494.     {
  1495.       AddTail(&li->ld_List, (struct Node *) n);
  1496.       li->ld_curNumber = li->ld_entries;
  1497.     }
  1498.     li->ld_curNode = n;
  1499.     ++li->ld_entries;
  1500.   }
  1501.  
  1502.   return (struct PackerNode *) n;
  1503. }
  1504.  
  1505. /* ---------------------- the cleanup stuff ---------------------------- */
  1506.  
  1507. void end(void)
  1508. {
  1509.   if(diskobject)    FreeDiskObject(diskobject);
  1510.   if(window)         CloseWindow(window);
  1511.   if(menus)        FreeMenus(menus);
  1512.   if(gadgList)        FreeGadgets(gadgList);
  1513.   if(VisualInfo)    FreeVisualInfo(VisualInfo);
  1514.   if(Scr)        UnlockPubScreen(0, Scr);
  1515.   if(GfxBase)        CloseLibrary((struct Library *) GfxBase);
  1516.   if(UtilityBase)    CloseLibrary(UtilityBase);
  1517.   if(GadToolsBase)    CloseLibrary(GadToolsBase);
  1518.   if(IntuitionBase)    CloseLibrary((struct Library *) IntuitionBase);
  1519.   if(IconBase)        CloseLibrary(IconBase);
  1520.   if(rda)        FreeArgs(rda);
  1521.   FreePackerList(&maindata);
  1522.   SDI_FreeLocale(&locdat);
  1523.   if(lock)        CurrentDir(lock);
  1524. }
  1525.  
  1526.